package com.dingding.service.usermangerservice.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.dingding.bean.databean.request.ReqCoupon;
import com.dingding.bean.databean.request.ReqDeposit;
import com.dingding.bean.databean.request.ReqGetUserWallet;
import com.dingding.bean.databean.response.DataResponse;
import com.dingding.bean.databean.response.ResCoupon;
import com.dingding.bean.databean.response.ResGetUserWallet;
import com.dingding.bean.entity.Depositdetail;
import com.dingding.bean.entity.UserLogin;
import com.dingding.bean.entity.Useraccount;
import com.dingding.common.core.config.ServiceCode;
import com.dingding.common.core.config.SystemCode;
import com.dingding.common.core.config.SystemConfig;
import com.dingding.common.core.util.DateFormatUtil;
import com.dingding.common.core.util.ToolUtil;
import com.dingding.dao.sql.UserAccountServiceSQL;
import com.dingding.facde.activity.dto.ExpiredCouponDTO;
import com.dingding.service.BaseService;
import com.dingding.service.usermangerservice.IUserAccountService;

/**
 * 
 * @ClassName: UserAccountServiceImpl
 * @Description:用户账户Service实现类
 * @author zhaochenguang
 * @date 2015-10-20 上午09:52:25
 * @version 叮叮搭车V2.0
 */
public class UserAccountServiceImpl extends BaseService implements IUserAccountService {

	private Logger log = Logger.getLogger(UserAccountServiceImpl.class);

	// 判断是正式环境还是测试环境，如果是测试环境，则不增加取消次数
	private boolean environmentParam = SystemConfig.isEnv_system();

	/**
	 * @Title: getUserAccountByUserId 
	 * @Description: 查询用户账户信息
	 * @param userId	用户id
	 * @param dataResponse 响应数据
	 * @author lijinchao
	 * @return Useraccount 用户账户信息
	 * @throws
	 */
	@Override
	@Transactional(readOnly = true)
	public Useraccount getUserAccountByUserId(String userId, DataResponse dataResponse) {

		// 账户信息
		Useraccount useraccount = null;
		// 创建查询条件
		Criterion criterion = Restrictions.eq("loginId", userId);

		try {

			// 获取账户信息
			useraccount = super.userAccountDao.queryCriteriaUnResult(criterion, false);
		} catch (Exception e) {
			log.error("用户提现查询用户账户信息时出现异常  类：" + this.getClass() + " userDeposit()", e);
			setStatus(dataResponse, SystemCode.ERROR);
			return null;
		}
		// 没有数据
		if (useraccount == null) {
			setStatus(dataResponse, SystemCode.USER_INFO_NOT_EXIST_ERROR);
			return null;
		}
		return useraccount;
	}

	/**
	 * @Title: getUserWallet
	 * @Description:获取用户钱包
	 * @author zhaochenguang
	 * @param reqGetUserWallet
	 *            请求数据封装
	 * @param dataResponse
	 *            响应数据封装
	 * @throws
	 * @Override
	 */
	@Transactional(readOnly = true)
	public void getUserWallet(ReqGetUserWallet reqGetUserWallet, DataResponse dataResponse) {

		if (reqGetUserWallet == null || ToolUtil.isBlank(reqGetUserWallet.getUserId())) {

			setStatus(dataResponse, SystemCode.DATA_NULL_ERROR);
			return;
		}

		// 获取用户的钱包信息
		ResGetUserWallet resUserWallet = getUserWalletInfo(reqGetUserWallet.getUserId());

		// 人民币：叮币 比率
		resUserWallet.setExchangeRate(ServiceCode.EXCHANGE_RULE);
		// 设置响应body
		dataResponse.setResponseBody(resUserWallet);
		// 设置响应码与相应信息
		setStatus(dataResponse, SystemCode.SUCCESS);

	}

	/**
	 * @Title: getUserWalletInfo
	 * @Description: 获取用户钱包
	 * @param userId 用户id
	 * @author fengshuonan
	 * @return ResGetUserWallet
	 * @throws
	 */
	public ResGetUserWallet getUserWalletInfo(String userId) {

		if (ToolUtil.isBlank(userId)) {
			log.error("获取用户钱包时，用户Id为空！UserAccountServiceImpl:getUserWalletInfo()");
			return null;
		}
		
		// 获取用户钱包信息
		List<Object[]> resGetUserWalletObj = null;
		try {
			// 根据用户登录id获取用户钱包详情
			resGetUserWalletObj = super.userAccountDao.sqlQueryListObj(UserAccountServiceSQL.GET_USER_WALLET, false,
					userId);
		} catch (Exception e) {
			log.error("获取用户钱包出现异常！ 类：UserAccountServiceImpl  getUserWallet()", e);
			return null;
		}

		// 判断返回的用户钱包信息是否为空
		if (resGetUserWalletObj == null || resGetUserWalletObj.size() <= 0) {
			return null;
		}

		// 获取即将过期的优惠券数量
		ExpiredCouponDTO expiredCouponDTO = super.activityFacade.getExpiredCouponNumber(userId);
		
		// 创建响应bean
		ResGetUserWallet resUserWallet = new ResGetUserWallet();

		// 设置响应bean(将List<Object[]>转为ResGetUserWallet类型)
		super.userAccountDao.setResGetUserWallet(resGetUserWalletObj, resUserWallet);
		
		// 判断获取到的即将过期的优惠券是否为空
		if(expiredCouponDTO != null){
			resUserWallet.setExpiredCouponNumber(expiredCouponDTO.getExpiredCouponNumber());
		}else{
			resUserWallet.setExpiredCouponNumber(0);
		}
		
		return resUserWallet;
	}

	@Override
	public void setStatus(DataResponse dataResponse, int status) {

		switch (status) {
		// 成功
		case SystemCode.SUCCESS:
			dataResponse.setResponseCode(SystemCode.SUCCESS);
			dataResponse.setResponseMessage(SystemCode.SUCCESS_MESSAGE);
			break;
		// 错误
		case SystemCode.ERROR:
			dataResponse.setResponseCode(SystemCode.ERROR);
			dataResponse.setResponseMessage(SystemCode.ERROR_MESSAGE);
			break;
		// 客户端传递的参数为空
		case SystemCode.DATA_NULL_ERROR:
			dataResponse.setResponseCode(SystemCode.DATA_NULL_ERROR);
			dataResponse.setResponseMessage(SystemCode.DATA_NULL_MESSAGE);
			break;
		// 账户余额不足
		case SystemCode.BALANCE_NOT_ENOUGH_ERROR:
			dataResponse.setResponseCode(SystemCode.BALANCE_NOT_ENOUGH_ERROR);
			dataResponse.setResponseMessage(SystemCode.BALANCE_NOT_ENOUGH_MESSAGE);
			break;
		// 用户不存在
		case SystemCode.USER_INFO_NOT_EXIST_ERROR:
			dataResponse.setResponseCode(SystemCode.USER_INFO_NOT_EXIST_ERROR);
			dataResponse.setResponseMessage(SystemCode.USER_INFO_NOT_EXIST_MESSAGE);
			break;
		// 提现次数达到上限
		case SystemCode.DEPOSIT_NUMBER_TOO_MANY_ERROR:
			dataResponse.setResponseCode(SystemCode.DEPOSIT_NUMBER_TOO_MANY_ERROR);
			dataResponse.setResponseMessage(SystemCode.DEPOSIT_NUMBER_TOO_MANY_MESSAGE);
			break;
			// 提现次数达到上限
		case SystemCode.DEPOSIT_MONEY_LITTLE_ERROR:
			dataResponse.setResponseCode(SystemCode.DEPOSIT_MONEY_LITTLE_ERROR);
			dataResponse.setResponseMessage(SystemCode.DEPOSIT_MONEY_LITTLE_MESSAGE);
			break;

		// 默认
		default:
			dataResponse.setResponseCode(SystemCode.ERROR);
			dataResponse.setResponseMessage(SystemCode.ERROR_MESSAGE);
			break;
		}
	}

	/**
	 * @Title: userDeposit
	 * @Description: 用户提现
	 * @param reqDeposit
	 *            客户端请求参数
	 * @param dataResponse
	 *            响应客户端对象
	 * @return void 返回类型
	 * @throws
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public void userDeposit(ReqDeposit reqDeposit, DataResponse dataResponse) {

		// 验证用户提现时传入的参数是否为空
		boolean isTrue = this.isValidateUserDepositTrue(reqDeposit);

		if (!isTrue) {
			log.error("提现请求参数为空:" + reqDeposit.toString());
			setStatus(dataResponse, SystemCode.DATA_NULL_ERROR);
			return;
		}

		// 请求提现用户id
		String userId = reqDeposit.getUserId();
		// 创建一个用户登录对象
		UserLogin userLogin = super.userLoginService.getUserLoginInfo(userId, dataResponse);
		// 无登录信息
		if (userLogin == null || userLogin.getDepositNumber() == null) {
			return;
		}

		// 账户信息
		Useraccount useraccount = this.getUserAccountByUserId(userId, dataResponse);
		// 查询账户信息有误
		if (useraccount == null || useraccount.getCurrencyAmount() == null || useraccount.getTotalDeposit() == null) {
			return;
		}

		// 提现金额不允许小于1块钱
		if(reqDeposit.getDepositMoney().compareTo(new BigDecimal(1)) < 0){
			setStatus(dataResponse, SystemCode.DEPOSIT_MONEY_LITTLE_ERROR);
			return;
		}
		
		// 提现钱数少于当前账户余额才可以提现
		// 如果提现钱数大于账户总余额
		if (reqDeposit.getDepositMoney().compareTo(useraccount.getCurrencyAmount()) > 0) {

			setStatus(dataResponse, SystemCode.BALANCE_NOT_ENOUGH_ERROR);
			return;
		}

		// 提现次数达到上限
		if (userLogin.getDepositNumber() != null && userLogin.getDepositNumber() >= 1) {

			setStatus(dataResponse, SystemCode.DEPOSIT_NUMBER_TOO_MANY_ERROR);
			return;
		}

		// 将客户端请求参数赋值给提现对象
		Depositdetail depositDetail = this.getDepositdetail(reqDeposit);

		try {
			// 向提现表中添加提现信息
			super.depositDetailDao.save(depositDetail);
		} catch (Exception e) {
			log.error("提现时添加提现记录出现异常 类:" + this.getClass() + " 方法:userDeposit()", e);
			setStatus(dataResponse, SystemCode.ERROR);
			return;
		}

		// 判断当前环境是正式环境还是测试环境(如果为测试环境则不需要增加提现次数)
		if (environmentParam) {
			// 提现次数加一
			userLogin.setDepositNumber(userLogin.getDepositNumber() + 1);
		}

		// 总钱数减去提现数
		useraccount.setCurrencyAmount(useraccount.getCurrencyAmount().subtract(reqDeposit.getDepositMoney()));
		// 提现钱数更新
		useraccount.setTotalDeposit(useraccount.getTotalDeposit().add(reqDeposit.getDepositMoney()));

		// 用户提现成功(等待人工提现)
		setStatus(dataResponse, SystemCode.SUCCESS);

	}

	/**
	 * @Title: validateUserDeposit
	 * @Description: 验证用户提现时客户端传入参数是否为空
	 * @param reqDeposit
	 *            客户端传入参数
	 * @return true 参数正确  false 参数错误
	 * @throws
	 */
	private boolean isValidateUserDepositTrue(ReqDeposit reqDeposit) {

		// 请求bean
		if (reqDeposit == null) {
			return false;
		}
		if (reqDeposit.getDepositMoney() == null) {
			return false;
		}
		// 用户id
		if (ToolUtil.isBlank(reqDeposit.getUserId())) {
			return false;
		}
		// 支付宝帐号
		if (ToolUtil.isBlank(reqDeposit.getZfbAccount())) {
			return false;
		}
		// 支付宝姓名
		if (ToolUtil.isBlank(reqDeposit.getZfbName())) {
			return false;
		}

		return true;
	}

	/**
	 * @Title: getDepositdetail
	 * @Description: 将 reqDeposit中的值赋给depositDetail
	 * @param reqDeposit
	 *            客户端请求参数
	 * @return Depositdetail 返回类型
	 * @throws
	 */
	public Depositdetail getDepositdetail(ReqDeposit reqDeposit) {

		// 创建提现对象
		Depositdetail depositDetail = new Depositdetail();

		// 提现主键Id 时间戳+6位随机数
		depositDetail.setDdId(DateFormatUtil.getTimeInMillis() + ToolUtil.generateCellPhoneValNum());
		// 用户ID
		depositDetail.setUserId(reqDeposit.getUserId());
		// 提现金额
		depositDetail.setDepositMoney(reqDeposit.getDepositMoney());
		// 支付宝账号
		depositDetail.setZfbAccount(reqDeposit.getZfbAccount());
		// 支付宝名称
		depositDetail.setZfbName(reqDeposit.getZfbName());
		// 提现时间
		depositDetail.setDepositTime(new Date());
		// 提现状态
		depositDetail.setDepositStatus(ServiceCode.DEPOSIT_STATUS_IN);

		return depositDetail;
	}

	/**
	 * @Title: getAllUserAccount 
	 * @Description: 获取全部用户账户列表(数据迁移专用)
	 * @return List<Useraccount>    返回类型 
	 * @throws
	 */
	@Override
	@Transactional(readOnly = true)
	public List<Useraccount> getAllUserAccount() {

		return super.userAccountDao.queryAll(false);
	}

	/**
	 * @Title: deleteAllUserAccount 
	 * @Description: 删除全部用户账户(数据迁移专用)
	 * @return boolean    返回类型 
	 * @throws
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public boolean deleteAllUserAccount() {

		// 全部订单
		int row = 0;
		try {
			row = super.userAccountDao.updateSqlRow("DELETE FROM useraccount");
		} catch (Exception e) {
			log.info("删除全部的用户账户信息时出现异常   类：" + this.getClass() + " deleteAllUserAccount()", e);
			return false;
		}

		// 判断删除订单是否成功
		if (row > 0) {
			return true;
		}

		return false;
	}

	/**
	 * @Title: updateAllUserAccount 
	 * @Description: 修改用户账户Id(数据迁移专用)
	 * @param useraccounts 用户账户列表
	 * @return boolean    返回类型 
	 * @throws
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public boolean updateAllUserAccount(List<Useraccount> useraccounts) {
		// 判断返回用户账户列表是否为空
		if (useraccounts != null && useraccounts.size() > 0) {

			for (Useraccount useraccount : useraccounts) {

				// 产生一个用户账户Id
				String oid = ToolUtil.getUid();

				useraccount.setUaId(oid);

				try {
					super.userAccountDao.save(useraccount);
					Thread.sleep(1);
				} catch (Exception e) {
					log.info("修改用户账户Id是出现异常   类：" + this.getClass() + " updateAllUserAccount()", e);
					return false;
				}

			}
			return true;
		}

		return false;
	}

	/**
	 * @Title: getCouponList 
	 * @Description: 我的出行券列表
	 * @param reqCoupon 获取我的出行券请求参数
	 * @param dataResponse 响应Bean
	 * @author YHQ
	 * @return void    返回类型 
	 */
	@Override
	@Transactional(readOnly = true)
	public void getCouponList(ReqCoupon reqCoupon, DataResponse dataResponse) {

		// 判断请求参数是否为空
		if (reqCoupon == null || ToolUtil.isBlank(reqCoupon.getLoginId())) {
			setStatus(dataResponse, SystemCode.DATA_NULL_ERROR);
			return;
		}

		try {
			// 我的出行券
			List<ResCoupon> resCoupons = super.userAccountDao.getCouponList(reqCoupon);

			// 响应请求
			dataResponse.setResponseBody(resCoupons);

			// 我的出行券请求成功
			setStatus(dataResponse, SystemCode.SUCCESS);
		} catch (Exception e) {
			log.error("获取我的出行券列表时出现异常  类：" + this.getClass() + " getCouponList()", e);
			// 我的出行券请求失败
			setStatus(dataResponse, SystemCode.ERROR);
		}

	}

	/**
	 * @Title: getResCoupon 
	 * @Description: 根据用户Id获取要使用的优惠券信息
	 * @param userId 用户Id
	 * @author YHQ
	 * @return ResCoupon    返回类型 
	 */
	@Override
	@Transactional(readOnly = true)
	public ResCoupon getResCoupon(String userId) {

		// 判断请求参数是否为空
		if (ToolUtil.isBlank(userId)) {
			return null;
		}

		return super.userAccountDao.getResCoupon(userId);
	}

}
